<template>
  <!-- spu表单 -->
  <div>
    <el-form ref="form" :model="spu" label-width="80px">
      <el-form-item label="SPU名称">
        <el-input v-model="spu.spuName"></el-input>
      </el-form-item>

      <el-form-item label="品牌">
        <el-select v-model="spu.tmId" placeholder="请选择品牌">
          <el-option v-for="(tm,index) in trademarkList" :key="tm.id" :label="tm.tmName" :value="tm.id"></el-option>
        </el-select>
      </el-form-item>

      <el-form-item label="SPU描述">
        <el-input v-model="spu.description" type="textarea" :rows="5" placeholder="请输入SPU描述" clearable></el-input>
      </el-form-item>

      <el-form-item label="SPU图片">
        <!-- list-type文件列表类型；file-list上传的文件列表 -->
        <el-upload
          action="/dev-api/admin/product/fileUpload"
          list-type="picture-card"
          :file-list="spuImageList"
          :on-preview="handlePictureCardPreview"
          :on-remove="handleRemove"
          :on-success="handleSuccess"
        >
          <i class="el-icon-plus"></i>
        </el-upload>
        <el-dialog :visible.sync="dialogVisible">
          <img width="100%" :src="dialogImageUrl" alt />
        </el-dialog>
      </el-form-item>

      <el-form-item label="销售属性">
        <el-select v-model="unSelectSaleAttrIdAndName" :placeholder="`还有${unSelectSaleAttr.length}项未选择`">
          <el-option
            v-for="item in unSelectSaleAttr"
            :key="item.id"
            :label="item.name"
            :value="`${item.id}&${item.name}`"
          ></el-option>
        </el-select>
        <el-button
          type="primary"
          icon="el-icon-plus"
          style="margin-left:10px"
          :disabled="!unSelectSaleAttrIdAndName"
          @click="addSaleAttr"
        >添加销售属性</el-button>
      </el-form-item>

      <!-- spu属性值表单 -->
      <el-form-item>
        <el-table :data="spu.spuSaleAttrList" border style="width: 100%">
          <el-table-column label="序号" width="180" type="index"></el-table-column>
          <el-table-column prop="saleAttrName" label="属性名" width="180"></el-table-column>
          <el-table-column prop="prop" label="属性值名称列表">
            <!-- 作用域插槽，拿到子组件内的每一个spuSaleAttr -->
            <template v-slot="{row,$index}">
              <!-- el-tag展示的是spuSaleAttrValueList列表里的每一个销售属性值 -->
              <el-tag
                v-for="(tag,idx) in row.spuSaleAttrValueList"
                :key="tag.id"
                :disable-transitions="false"
                closable
                @close="handleClose(row,idx)"
              >{{ tag.saleAttrValueName }}</el-tag>
              <!-- 标签输入框 -->
              <el-input
                v-if="row.inputVisible"
                ref="input"
                v-model="row.inputValue"
                class="input-new-tag"
                size="small"
                @blur="handleInputConfirm(row)"
                @keyup.enter.native="$event.target.blur()"
              ></el-input>
              <!-- 添加新属性值按钮 -->
              <el-button
                v-else
                class="button-new-tag"
                size="small"
                icon="el-icon-plus"
                @click="addSaleAttrValue(row)"
              >属性值</el-button>
            </template>
          </el-table-column>
          <el-table-column prop="address" label="操作" width="80">
            <template v-slot="{row,$index}">
              <!-- 删除属性按钮 -->
              <el-popconfirm :title="`你确定要删除'${row.saleAttrName}'吗?`" @onConfirm="deleteSaleAttr($index)">
                <el-button slot="reference" type="danger" icon="el-icon-delete"></el-button>
              </el-popconfirm>
            </template>
          </el-table-column>
        </el-table>
      </el-form-item>

      <!-- 提交/取消按钮 -->
      <el-form-item>
        <el-button type="primary" @click="addOrUpdateSpu">保存</el-button>
        <el-button @click="clear">取消</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
export default {
  name: 'SpuForm',
  data () {
    return {
      // spu信息属性
      spu: {
        // 三级分类id
        category3Id: '',
        // 描述
        description: '',
        // spu名称
        id: '',
        // 平台的id
        spuName: '',
        // 平台的id
        tmId: '',
        // 收集spu图片信息
        spuImageList: [
          // {
          //   id: 0,
          //   imgName: '',
          //   imgUrl: '',
          //   spuId: 0
          // }
        ],
        // 平台属性与属性值收集
        spuSaleAttrList: [
          // {
          //   baseSaleAttrId: 0,
          //   id: 0,
          //   saleAttrName: '',
          //   spuId: 0,
          //   spuSaleAttrValueList: [
          //     {
          //       baseSaleAttrId: 0,
          //       id: 0,
          //       isChecked: '',
          //       saleAttrName: '',
          //       saleAttrValueName: '',
          //       spuId: 0
          //     }
          //   ]
          // }
        ]
      },
      // 品牌信息
      trademarkList: [],
      // spu图标
      spuImageList: [],
      // 售卖属性
      spuSaleAttrList: [],
      dialogVisible: false,
      dialogImageUrl: '',
      // 收集未选择属性的id
      unSelectSaleAttrIdAndName: ''
    }
  },
  computed: {
    // 剩余未选择的属性名
    unSelectSaleAttr () {
      // 利用filter过滤spu中已经有的属性(利用两个for循环)
      return this.spuSaleAttrList.filter((item) => {
        return this.spu.spuSaleAttrList.every((elem) => {
          // 两个对象的id不相等，说明spu不存在这个id的属性
          if (elem.saleAttrName !== item.name) {
            return true
          }
        })
      })
    }
  },
  methods: {
    // 删除照片时触发
    handleRemove (file, fileList) {
      // console.log(file, fileList)
      // file为删除的那一张照片，fileList为照片墙剩余的照片数
      this.spuImageList = fileList
    },

    // 点击显示大图时触发
    handlePictureCardPreview (file) {
      this.dialogImageUrl = file.url
      this.dialogVisible = true
    },

    // 图片上传成功时触发
    handleSuccess (response, file, fileList) {
      // 将服务器url替换本地url
      file.url = response.data
      // console.log(response, file, fileList)
      this.spuImageList.push(file)
    },

    // 初始化spu表单数据
    async initSpuData (spu) {
      // 获取spu信息
      const spuResult = await this.$api.spu.reqSpu(spu.id)
      if (spuResult.code === 200) {
        this.spu = spuResult.data
      } else {
        this.$message.error('获取spu信息失败')
      }
      // 获取品牌信息
      const trademarkResult = await this.$api.spu.reqTrademarkList()
      if (trademarkResult.code === 200) {
        this.trademarkList = trademarkResult.data
      } else {
        this.$message.error('获取品牌信息失败')
      }
      // 获取spu图标
      const spuImageResult = await this.$api.spu.reqSpuImage(spu.id)
      if (spuImageResult.code === 200) {
        // 对服务器返回的数据进行修改，以便符合el-upload中file-list对数组的格式要求
        spuImageResult.data.forEach(item => {
          item.name = item.imgName
          item.url = item.imgUrl
        })
        this.spuImageList = spuImageResult.data
      } else {
        this.$message.error('获取spu图标信息失败')
      }
      // 获取平台售卖属性
      const saleAttrResult = await this.$api.spu.reqSaleAttrList()
      if (saleAttrResult.code === 200) {
        this.spuSaleAttrList = saleAttrResult.data
      } else {
        this.$message.error('获取售卖属性信息失败')
      }
    },

    // 添加销售属性按钮回调函数
    addSaleAttr () {
      // 将unSelectSaleAttrIdAndName收集到的属性分割，并进行解构赋值
      const [baseSaleAttrId, saleAttrName] = this.unSelectSaleAttrIdAndName.split('&')
      // 创建一个新的销售属性对象，并把它push到spu的销售属性列表里
      const newSaleAttr = {
        baseSaleAttrId,
        saleAttrName,
        spuSaleAttrValueList: []
      }
      this.spu.spuSaleAttrList.push(newSaleAttr)
      // 点击添加属性后后清除下拉选择栏里的数据
      this.unSelectSaleAttrIdAndName = ''
    },

    // 【+属性值】按钮的回调函数
    addSaleAttrValue (row) {
      // 这种方法是错误的，因为inputVisible不是vue初始化时就存在的元素，
      // 使用这种赋值方式得到的数据不是响应式数据
      // row.inputVisible = true
      // 使用set添加的数据才是响应式数据
      this.$set(row, 'inputVisible', true)
      this.$set(row, 'inputValue', '')
      this.$nextTick(() => {
        this.$refs.input.focus()
      })
    },

    // 属性值输入框失去焦点/按回车后回调
    handleInputConfirm (row) {
      // const saleAttrValueName = row.inputValue
      const { baseSaleAttrId, saleAttrName, inputValue } = row
      // 属性值不能为空
      if (inputValue.trim() === '') {
        this.$message.warning('输入的属性值不能为空!')
        return
      }
      // 属性值不能重复(返回true表示有重复，false表示不重复)
      const flag = row.spuSaleAttrValueList.some(item => item.saleAttrValueName === row.inputValue)
      if (flag) {
        this.$message.warning('输入的属性值不能重复!')
        return
      }
      const newSaleAttrValue = { baseSaleAttrId, saleAttrName, saleAttrValueName: inputValue }
      row.spuSaleAttrValueList.push(newSaleAttrValue)
      // 关闭并清空输入框
      row.inputVisible = false
      row.inputValue = ''
    },

    // 删除销售属性
    deleteSaleAttr (index) {
      this.spu.spuSaleAttrList.splice(index, 1)
    },

    // 删除销售属性值（删除标签）
    handleClose (row, idx) {
      row.spuSaleAttrValueList.splice(idx, 1)
    },

    // 添加或修改spu提交给服务器
    async addOrUpdateSpu () {
      // 使用map整理参数，筛选出要提交到服务器的数据
      this.spu.spuImageList = this.spuImageList.map(item => {
        // console.log(item)
        return {
          imgName: item.name,
          imgUrl: item.url
        }
      })
      // console.log(this.spu.spuImageList)
      const result = await this.$api.spu.reqAddOrUpdateSpu(this.spu)
      if (result.code === 200) {
        this.$message.success('spu修改成功!')
        this.clear()
        // 返回spu列表页
        this.$emit('changeScene', { scene: 0, flag: this.spu.id ? '修改' : '添加' })
      } else {
        this.$message.error('spu信息提交失败!')
      }
    },

    // 点击【添加spu】按钮时触发的函数，获取品牌信息和属性信息
    async addSpuData (category3Id) {
      // 获取品牌信息
      const trademarkResult = await this.$api.spu.reqTrademarkList()
      if (trademarkResult.code === 200) {
        this.trademarkList = trademarkResult.data
      } else {
        this.$message.error('获取品牌信息失败')
      }
      // 获取平台售卖属性
      const saleAttrResult = await this.$api.spu.reqSaleAttrList()
      if (saleAttrResult.code === 200) {
        this.spuSaleAttrList = saleAttrResult.data
      } else {
        this.$message.error('获取售卖属性信息失败')
      }
      // 添加spu时收集到的category3Id
      this.spu.category3Id = category3Id
    },

    // 取消按钮回调函数
    clear () {
      // 返回spu列表页后清理spuForm表格中的所有数据
      this.$emit('changeScene', { scene: 0, flag: '' })
      // 清理数据
      // $option用于组件的初始化选项。$option.data获取到实例初始化的data对象数据，并用他替换掉之前的数据
      Object.assign(this._data, this.$options.data())
    }
  }
}
</script>

<style>
.el-tag + .el-tag {
  margin-left: 10px;
}
.button-new-tag {
  margin-left: 10px;
  height: 32px;
  line-height: 30px;
  padding-top: 0;
  padding-bottom: 0;
}
.input-new-tag {
  width: 90px;
  margin-left: 10px;
  vertical-align: bottom;
}
</style>
